package com.niiwoo.civet.mobile.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.mobile.shiro.MobileUserDetailException;
import com.niiwoo.civet.mobile.util.ParameterValidator;
import com.niiwoo.civet.mobile.vo.request.AccountStatusRequestVO;
import com.niiwoo.civet.mobile.vo.request.RegisterRequestVO2;
import com.niiwoo.civet.mobile.vo.request.user.*;
import com.niiwoo.civet.mobile.vo.response.user.*;
import com.niiwoo.civet.user.constants.LoginAccountErrorCode;
import com.niiwoo.civet.user.dto.request.*;
import com.niiwoo.civet.user.dto.response.GetInviteCodeResponseDTO;
import com.niiwoo.civet.user.dto.response.UserBasicInfoResponseDTO;
import com.niiwoo.civet.user.enums.UserEnum;
import com.niiwoo.civet.user.enums.UserSMSTypeEnum;
import com.niiwoo.civet.user.service.UserBasicInfoDubboService;
import com.niiwoo.civet.user.service.UserLoginAccountDubboService;
import com.niiwoo.civet.user.service.UserSMSDubboService;
import com.niiwoo.tripod.base.helper.StringHelper;
import com.niiwoo.tripod.base.utils.DateUtils;
import com.niiwoo.tripod.consumer.helper.Exceptions;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.web.annotation.AuthIgnore;
import com.niiwoo.tripod.web.enums.DeviceTypeEnum;
import com.niiwoo.tripod.web.properties.ShiroProperties;
import com.niiwoo.tripod.web.shiro.UsernamePasswordDeviceToken;
import com.niiwoo.tripod.web.util.PrincipalContext;
import com.niiwoo.tripod.web.util.RequestUtil;
import com.niiwoo.tripod.web.vo.Empty;
import com.niiwoo.tripod.web.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;

/**
 * Created by zhangwanli on 2017/9/20.
 */
@RestController
@RequestMapping("/user")
@Api(tags = "用户(李健)", description = "/user")
@Slf4j
public class UserController {

    @Reference(version = "1.0.0")
    private UserLoginAccountDubboService userLoginAccountService;

    @Reference(version = "1.0.0")
    private UserBasicInfoDubboService userBasicInfoDubboService;
    @Reference(version = "1.0.0")
    private UserSMSDubboService userSMSDubboService;
    @Autowired
    private ShiroProperties shiroProperties;

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    @PostMapping("/account/status")
    @ApiOperation(value = "手机号是否注册", notes = "0000表示已注册，错误码：USR19054-登录失败，用户名或密码错误 USR19056-您的手机号输入错误")
    @AuthIgnore
    public Empty accountStatus(@RequestBody @Valid AccountStatusRequestVO vo) {
        if (StringUtils.isBlank(vo.getLoginMobileNo()) || !ParameterValidator.isMobileNo(vo.getLoginMobileNo())) {
            throw new BizException(LoginAccountErrorCode.LOGIN_MOBILENO_FORMAT_ERROR);
        }
        LoginAccountRequestDTO dto = new LoginAccountRequestDTO();
        dto.setLoginMobileNo(vo.getLoginMobileNo());
        dto.setIsCheckLoginForbid(false);
        if (userLoginAccountService.getLoginAccount(dto) == null) {
            throw new BizException(LoginAccountErrorCode.USERS_LOGIN_FAIL);
        }
        return Empty.getInstance();
    }

    @PostMapping("/registerAndLogin")
    @ApiOperation(value = "注册和登录", notes = "USR19056-您的手机号输入错误 USR19007-缺少登录名 USR19009-为保障信息安全，登录密码错误超过5次，账户自动锁定24小时。 可以通过忘记密码进行解锁。 如需帮助请联系客服：400-0683-666 USR19010-缺少短信验证码 USR19011-验证码错误或过期，请重新输入 USR19006-用户不存在 USR19054-登录失败，用户名或密码错误 USR19057-密码错误，请重输！您还有1次机会，为保障信息安全，错误5次系统将锁码24小时。 USR19012-登录失败，用户名或密码错误 USR19013-登录失败，用户名或密码错误 USR19001-设备类型错误 USR19051-密码格式错误，请重新输入 USR19056-您的手机号输入错误 USR19055-邀请人手机号有误，请重新填写 USR19002-注册失败 USR19005-您已在你我金融注册，请直接登录 USR19011-验证码错误或过期，请重新输入")
    @AuthIgnore
    public Result registerAndLogin(HttpServletRequest httpServletRequest, @RequestBody @Valid RegisterRequestVO2 vo) throws Throwable {
        Result<RegisterResponseVO> registerResponseVOResult = this.register(httpServletRequest, vo);
        if (!registerResponseVOResult.getRespCode().equals("0000")) {
            return registerResponseVOResult;
        }
        LoginRequestVO loginRequestVO = new LoginRequestVO();
        switch (UserEnum.RegisterDeviceType.enumOf(vo.getDeviceType().byteValue())) {
            case IOS: {loginRequestVO.setDeviceType("IOS/mobile");} break;
            case ANDROID:{loginRequestVO.setDeviceType("Android/mobile");} break;
            case WEB:{loginRequestVO.setDeviceType("H5");} break;
        }
        loginRequestVO.setLoginMobileNo(vo.getLoginMobileNo());
        loginRequestVO.setPassword(vo.getPassword());
        loginRequestVO.setProvinceName(vo.getProvinceName());
        loginRequestVO.setCityName(vo.getCityName());
        loginRequestVO.setAreaName(vo.getAreaName());
        loginRequestVO.setAddress(vo.getAddress());
        loginRequestVO.setLongitude(vo.getLongitude());
        loginRequestVO.setLatitude(vo.getLatitude());
        loginRequestVO.setClientAccessIP(vo.getClientAccessIP());
        loginRequestVO.setSmsCode(vo.getSmsCode());
        loginRequestVO.setMapType(vo.getMapType());
        loginRequestVO.setMacAddress(vo.getMacAddress());
        loginRequestVO.setWifiSSID(vo.getWifiSSID());
        loginRequestVO.setDownChannel(vo.getDownChannel());
        loginRequestVO.setAppVersion(vo.getAppVersion());
        loginRequestVO.setDeviceId(vo.getDeviceId());
        loginRequestVO.setSimMobilePhone(vo.getSimMobilePhone());
        loginRequestVO.setOs(vo.getOs());
        loginRequestVO.setOsVersion(vo.getOsVersion());
        loginRequestVO.setResolution(vo.getResolution());
        loginRequestVO.setBrand(vo.getBrand());
        loginRequestVO.setPhoneModel(vo.getPhoneModel());
        loginRequestVO.setEquipmentStatus(vo.getEquipmentStatus());
        loginRequestVO.setDualSim(vo.getDualSim());
        loginRequestVO.setJiGuangPushId(vo.getJiGuangPushId());
        loginRequestVO.setBlackBox(vo.getBlackBox());
        return this.login(httpServletRequest, loginRequestVO);
    }


    @PostMapping("/register")
    @ApiOperation(value = "注册(黄斌)", notes = "USR19001-设备类型错误 USR19051-密码格式错误，请重新输入 USR19056-您的手机号输入错误 USR19055-邀请人手机号有误，请重新填写 USR19002-注册失败 USR19005-您已在你我金融注册，请直接登录 USR19011-验证码错误或过期，请重新输入")
    @AuthIgnore
    public Result<RegisterResponseVO> register(HttpServletRequest httpServletRequest, @RequestBody @Valid RegisterRequestVO vo) {
        String userRealIP = RequestUtil.getUserRealIP(httpServletRequest);
        vo.setIpAddress(userRealIP);
        log.info("注册接口###IP###mobileNo={}, ip={}", vo.getLoginMobileNo(), userRealIP);
        // 参数校验
        UserEnum.RegisterDeviceType deviceType = UserEnum.RegisterDeviceType.enumOf(vo.getDeviceType().byteValue());
        if (deviceType == null) {
            Exceptions.throwBizException(LoginAccountErrorCode.DEVICE_TYPE_ERROR);
        }
        if (deviceType != UserEnum.RegisterDeviceType.WEB) {
            if (StringUtils.isBlank(vo.getAppVersion())) {
                throw new BizException(LoginAccountErrorCode.APP_VERSION_IS_EMPTY);
            }
            if (StringUtils.isBlank(vo.getAppDownloadChannel())) {
                throw new BizException(LoginAccountErrorCode.APP_DOWNLOAD_CHANNEL_IS_EMPTY);
            }
        }
        if (!ParameterValidator.valid(vo.getPassword())) {
            throw new BizException(LoginAccountErrorCode.PASSWORD_FORMAT_ERROR);
        }
        if (StringUtils.isBlank(vo.getLoginMobileNo()) || !ParameterValidator.isMobileNo(vo.getLoginMobileNo())) {
            throw new BizException(LoginAccountErrorCode.LOGIN_MOBILENO_FORMAT_ERROR);
        }
		if (StringUtils.isNotBlank(vo.getInviterMobileNo()) && vo.getLoginMobileNo().equals(vo.getInviterMobileNo())) {
            throw new BizException(LoginAccountErrorCode.INVITER_MOBILENO_FORMAT_ERROR);
        }
        //短信验证
        userLoginAccountService.validSMSCode(vo.getLoginMobileNo(),vo.getSmsCode(), UserSMSTypeEnum.REGISTER);
        String salt = getRandomSalt();
        LoginAccountRegisterRequestDTO dto = new LoginAccountRegisterRequestDTO();
        // 登录手机号
        dto.setLoginMobileNo(vo.getLoginMobileNo());
        // 盐值
        dto.setSalt(salt);
        // 密码哈希值
        dto.setPassword(getPasswordHash(vo.getPassword(), salt));
        // 短信验证码
        dto.setSmsCode(vo.getSmsCode());
        // 邀请人手机号
        dto.setInviterMobileNo(vo.getInviterMobileNo());
        // 省级名称
        dto.setProvinceName(vo.getProvinceName());
        // 市级名称
        dto.setCityName(vo.getCityName());
        // 区级名称
        dto.setAreaName(vo.getAreaName());
        // 详细地址
        dto.setAddress(vo.getAddress());
        // 经度
        dto.setLongitude(vo.getLongitude());
        // 纬度
        dto.setLatitude(vo.getLatitude());
        // APP版本
        dto.setAppVersion(vo.getAppVersion());
        // 设备类型
        dto.setDeviceType(deviceType);
        // 注册渠道
        switch (deviceType) {
            case IOS:
                dto.setRegisterChannel(UserEnum.RegisterChannel.PLATFORM_APP_IOS); break;
            case ANDROID:
                dto.setRegisterChannel(UserEnum.RegisterChannel.PLATFORM_APP_ANDROID); break;
            case WEB:
                dto.setRegisterChannel(UserEnum.RegisterChannel.PLATFORM_H5); break;
        }
        // APP下载渠道
        dto.setAppDownloadChannel(vo.getAppDownloadChannel());
        dto.setIpAddress(vo.getIpAddress());
        dto.setLongitude(vo.getLongitude());
        dto.setLatitude(vo.getLatitude());
        dto.setMapType(vo.getMapType());
        dto.setMacAddress(vo.getMacAddress());
        dto.setOperators(vo.getOperators());
        if (!"unknown".equals(vo.getWifiSSID())) {
            dto.setWifiSSID(vo.getWifiSSID());
        }
        dto.setDownChannel(vo.getDownChannel());
        dto.setAppVersion(vo.getAppVersion());
        if (!"000".equals(vo.getDeviceId())) {
            dto.setDeviceId(vo.getDeviceId());
        }
        dto.setSimMobilePhone(vo.getSimMobilePhone());
        dto.setOs(vo.getOs());
        dto.setOsVersion(vo.getOs());
        dto.setResolution(vo.getResolution());
        dto.setBrand(vo.getBrand());
        dto.setPhoneModel(vo.getPhoneModel());
        dto.setEquipmentStatus(vo.getEquipmentStatus());
        dto.setDualSim(vo.getDualSim());
        dto.setJiGuangPushId(vo.getJiGuangPushId());
        dto.setRecommendUrl(vo.getRecommendUrl());
        dto.setInviterUserId(StringUtils.isNotBlank(vo.getInviterUserId()) ? vo.getInviterUserId() : null);
        dto.setFestivalFlag(vo.getFestivalFlag() != null ? vo.getFestivalFlag() : null);
        dto.setIsInvest(vo.getIsInvest());
        // 注册
        return Optional.ofNullable(userLoginAccountService.register(dto))
                        .map(userId -> {
                            RegisterResponseVO responseVO = new RegisterResponseVO();
                            responseVO.setLoginMobileNo(vo.getLoginMobileNo());
                            responseVO.setUserId(userId);
                            return Result.with(responseVO);
                        })
                        .orElseThrow(() -> new BizException(LoginAccountErrorCode.REGISTER_FAIL));
    }

    @PostMapping("/registerForBBS")
    @ApiOperation(value = "注册(杨玉威)", notes = "USR19001-设备类型错误 USR19051-密码格式错误，请重新输入 USR19056-您的手机号输入错误 USR19055-邀请人手机号有误，请重新填写 USR19002-注册失败 USR19005-您已在你我金融注册，请直接登录 USR19011-验证码错误或过期，请重新输入")
    @AuthIgnore
    public Result<Map<String,Object>> registerForBBS(@RequestBody @Valid RegisterForBBSRequestVO vo) {
        vo.setDeviceType(2); //网页模式
        // 参数校验
        UserEnum.RegisterDeviceType deviceType = UserEnum.RegisterDeviceType.enumOf(vo.getDeviceType().byteValue());
        if (deviceType == null) {
            Exceptions.throwBizException(LoginAccountErrorCode.DEVICE_TYPE_ERROR);
        }

        if (!ParameterValidator.valid(vo.getPassWord())) {
            throw new BizException(LoginAccountErrorCode.PASSWORD_FORMAT_ERROR);
        }
        if (StringUtils.isBlank(vo.getPhone()) || !ParameterValidator.isMobileNo(vo.getPhone())) {
            throw new BizException(LoginAccountErrorCode.LOGIN_MOBILENO_FORMAT_ERROR);
        }

        //短信验证
        //userLoginAccountService.validSMSCode(vo.getLoginMobileNo(),vo.getSmsCode(), UserSMSTypeEnum.REGISTER);
        String salt = getRandomSalt();
        LoginAccountRegisterRequestDTO dto = new LoginAccountRegisterRequestDTO();
        // 登录手机号
        dto.setLoginMobileNo(vo.getPhone());
        // 盐值
        dto.setSalt(salt);
        // 密码哈希值
        dto.setPassword(getPasswordHash(vo.getPassWord(), salt));
        // 短信验证码
        //dto.setSmsCode(vo.getSmsCode());

        // 设备类型
        dto.setDeviceType(deviceType);
        // 注册渠道
        dto.setRegisterChannel(UserEnum.RegisterChannel.PLATFORM_H5);
        String userId = userLoginAccountService.register(dto);
        Map<String,Object> data = new HashMap<String,Object>();
        RegisterForBBSResponseVO responseVO = new RegisterForBBSResponseVO();
        responseVO.setMobileNo(vo.getPhone());
        responseVO.setUserId(userId);
        responseVO.setAddDate(DateUtils.format(new Date(),"yyyyMMddHHmmss"));
        responseVO.setEmail(vo.getEmail());
        responseVO.setNickName(vo.getNickName());
        responseVO.setUname(vo.getUserName());
        data.put("user",responseVO);
        data.put("userToken","");
        // 注册
        return Result.with(data);
    }

    @ApiOperation(value = "发送注册短信验证码(杨玉威)")
    @RequestMapping(path = "/getRegisterCode", method = RequestMethod.POST)
    @AuthIgnore
    public Result<UserSMSBBSResponseVO> sendSMS(@RequestBody @Valid UserSMSBBSRequestVO request) {
        request.setBizType(new Integer(1));
        UserSMSTypeEnum smsType = UserSMSTypeEnum.of(request.getBizType().byteValue());

        RefreshSMSCodeRequestDTO refreshSMSCodeRequestDTO = new RefreshSMSCodeRequestDTO();
        refreshSMSCodeRequestDTO.setSmsType(smsType);
        refreshSMSCodeRequestDTO.setLoginMobileNo(request.getPhone());
        UserSMSBBSResponseVO responseVO = new UserSMSBBSResponseVO();
        if (!userSMSDubboService.createSMS(refreshSMSCodeRequestDTO)) {
            responseVO.setState("3");
            //throw new BizException(LoginAccountErrorCode.SMS_SEND_FAIL);
        }else{
            responseVO.setState("1");
        }
        return Result.with(responseVO);
    }

    @ApiOperation(value = "验证注册短信验证码(杨玉威)")
    @RequestMapping(path = "/checkRegisterCode", method = RequestMethod.POST)
    @AuthIgnore
    public Result<String> checkSMS(@RequestBody @Valid UserCheckSMSRequestVO vo) {
        //短信验证
        String result = userLoginAccountService.validRegisterSMSCode(vo.getPhone(),vo.getMsgCode(), UserSMSTypeEnum.REGISTER);

        return Result.with(result);
    }
    /**
     * 获取密码哈希值
     *
     * @param password 密码明文
     * @param salt     盐值
     * @return 密码哈希值
     */
    private String getPasswordHash(String password, String salt) {
        ShiroProperties.HashedCredentialProperties hashedCredential = shiroProperties.getHashedCredential();
        return new SimpleHash(hashedCredential.getHashAlgorithName(), ParameterValidator.toTuanDaiPassword(password), salt, hashedCredential.getHashIterations()).toString();
    }

    /**
     * 获取随机盐值
     *
     * @return 盐值
     */
    private String getRandomSalt() {
        return StringHelper.genRandomStr(5);
    }


    @PostMapping("/login")
    @ApiOperation(value = "登录(黄斌)", notes = "USR19056-您的手机号输入错误 USR19007-缺少登录名 USR19009-为保障信息安全，登录密码错误超过5次，账户自动锁定24小时。 可以通过忘记密码进行解锁。 如需帮助请联系客服：400-0683-666 USR19010-缺少短信验证码 USR19011-验证码错误或过期，请重新输入 USR19006-用户不存在 USR19054-登录失败，用户名或密码错误 USR19057-密码错误，请重输！您还有1次机会，为保障信息安全，错误5次系统将锁码24小时。 USR19012-登录失败，用户名或密码错误 USR19013-登录失败，用户名或密码错误")
    @AuthIgnore
    public Result<LoginResponseVO> login(HttpServletRequest httpServletRequest, @RequestBody @Valid LoginRequestVO request) throws Throwable {
        String userRealIP = RequestUtil.getUserRealIP(httpServletRequest);
        request.setClientAccessIP(userRealIP);
        log.info("登录接口###IP###mobileNo={}, ip={}", request.getLoginMobileNo(), userRealIP);
//        JSONObject parse = JSONObject.parseObject(JSON.toJSONString(request));
//        parse.remove("password");
//        log.info("登录接口,请求参数={}", parse.toJSONString());
        log.info("登录接口,请求参数={}", JSON.toJSONString(request));
        if (StringUtils.isBlank(request.getLoginMobileNo()) || !ParameterValidator.isMobileNo(request.getLoginMobileNo())) {
            throw new BizException(LoginAccountErrorCode.LOGIN_MOBILENO_FORMAT_ERROR);
        }
        if (!request.getDeviceType().equals("H5") && StringUtils.isBlank(request.getBlackBox())) {
            throw new BizException(LoginAccountErrorCode.BLACK_BOX_IS_EMPTY);
        }
        // 登录前验证
        BeforeLoginRequestDTO beforeLoginRequestDTO = new BeforeLoginRequestDTO();
        beforeLoginRequestDTO.setLoginMobileNo(request.getLoginMobileNo());
        beforeLoginRequestDTO.setSmsCode(request.getSmsCode());
        beforeLoginRequestDTO.setPassword(request.getPassword());
        userLoginAccountService.beforeLoginValid(beforeLoginRequestDTO);
        UsernamePasswordDeviceToken token = new UsernamePasswordDeviceToken(request.getLoginMobileNo(), ParameterValidator.toTuanDaiPassword(request.getPassword()), DeviceTypeEnum.enumOf(request.getDeviceType()));
        try {
            // 登录验证
            SecurityUtils.getSubject().login(token);
        } catch (UnknownAccountException e) {
            // 账号不存在
            Exceptions.throwBizException(LoginAccountErrorCode.USERS_NOT_EXIST);
        } catch (IncorrectCredentialsException e) {
            // 密码错误处理
            postLoginHandleIfPasswordError(request);
        } catch (MobileUserDetailException e) {
            // 其他业务异常
            throw e.getCause();
        } catch (AuthenticationException e) {
            Exceptions.throwBizException(LoginAccountErrorCode.USERS_LOGIN_FAIL);
        }
        // 登录后处理

        String newToken = SecurityUtils.getSubject().getSession().getId().toString();
        postLoginHandleIfLoginSuccess(request, newToken, String.valueOf(PrincipalContext.getUserId()));
        LoginResponseVO response = new LoginResponseVO();
        response.setToken(newToken);
        response.setUserId(String.valueOf(PrincipalContext.getUserId()));
        response.setLoginMobileNo(request.getLoginMobileNo());
        response.setLastLoginTime(new Date());
        log.info("登录接口,响应结果={}", JSON.toJSONString(response));
        return Result.with(response);
    }

    @PostMapping("/loginForBBS")
    @ApiOperation(value = "登录(杨玉威)", notes = "USR19056-您的手机号输入错误 USR19007-缺少登录名 USR19009-为保障信息安全，登录密码错误超过5次，账户自动锁定24小时。 可以通过忘记密码进行解锁。 如需帮助请联系客服：400-0683-666 USR19010-缺少短信验证码 USR19011-验证码错误或过期，请重新输入 USR19006-用户不存在 USR19054-登录失败，用户名或密码错误 USR19057-密码错误，请重输！您还有1次机会，为保障信息安全，错误5次系统将锁码24小时。 USR19012-登录失败，用户名或密码错误 USR19013-登录失败，用户名或密码错误")
    @AuthIgnore
    public Result<HashMap<String,Object>> loginForBBS(@RequestBody @Valid LoginRequestBBSVO requestBBS) throws Throwable {

        LoginRequestVO request = new LoginRequestVO();
        request.setLoginMobileNo(requestBBS.getUserName());
        request.setPassword(requestBBS.getPassword());
        request.setDeviceType("H5"); //设备
        request.setDualSim(new Integer(0));
        request.setEquipmentStatus(new Integer(0));
        request.setMapType(new Integer(0));
        if (StringUtils.isBlank(request.getLoginMobileNo()) || !ParameterValidator.isMobileNo(request.getLoginMobileNo())) {
            throw new BizException(LoginAccountErrorCode.LOGIN_MOBILENO_FORMAT_ERROR);
        }
        if (!request.getDeviceType().equals("H5") && StringUtils.isBlank(request.getBlackBox())) {
            throw new BizException(LoginAccountErrorCode.BLACK_BOX_IS_EMPTY);
        }
        // 登录前验证
        BeforeLoginRequestDTO beforeLoginRequestDTO = new BeforeLoginRequestDTO();
        beforeLoginRequestDTO.setLoginMobileNo(request.getLoginMobileNo());
        beforeLoginRequestDTO.setSmsCode(request.getSmsCode());
        beforeLoginRequestDTO.setPassword(request.getPassword());
        userLoginAccountService.beforeLoginValid(beforeLoginRequestDTO);
        UsernamePasswordDeviceToken token = new UsernamePasswordDeviceToken(request.getLoginMobileNo(), ParameterValidator.toTuanDaiPassword(request.getPassword()), DeviceTypeEnum.enumOf(request.getDeviceType()));
        try {
            // 登录验证
            SecurityUtils.getSubject().login(token);
        } catch (UnknownAccountException e) {
            // 账号不存在
            Exceptions.throwBizException(LoginAccountErrorCode.USERS_NOT_EXIST);
        } catch (IncorrectCredentialsException e) {
            // 密码错误处理
            postLoginHandleIfPasswordError(request);
        } catch (MobileUserDetailException e) {
            // 其他业务异常
            throw e.getCause();
        } catch (AuthenticationException e) {
            Exceptions.throwBizException(LoginAccountErrorCode.USERS_LOGIN_FAIL);
        }
        String userId = String.valueOf(PrincipalContext.getUserId());
        UserBasicInfoResponseDTO userBasicInfoResponseDTO = userBasicInfoDubboService.getUserBasicInfo(userId);
        // 登录后处理
        HashMap<String,Object> data = new HashMap<String,Object>();
        LoginBBSResponseVO responseVO = new LoginBBSResponseVO();
        data.put("userToken","");
        responseVO.setUname("");
        responseVO.setUserId(userId);
        responseVO.setNickName(userBasicInfoResponseDTO.getNickName());
        responseVO.setHeadImage(userBasicInfoResponseDTO.getHeadImage());
        responseVO.setMobileNo(userBasicInfoResponseDTO.getMobileNo());
        responseVO.setAddDate(DateUtils.formatDate(userBasicInfoResponseDTO.getCreateTime(),"yyyyMMddHHmmss"));
        responseVO.setIsTwoCode(""); // 数据库没有这个字段
        responseVO.setLevel("1"); // 数据库没有这个字段
        responseVO.setIsValidateIdentity(false);//是否实名认证
        responseVO.setAuthenState("0"); // 数据库没有这个字段
        responseVO.setCreditGrantingAmount("0"); // 数据库没有这个字段
        responseVO.setUsedCreditGrantingAmount("0"); // 数据库没有这个字段
        responseVO.setCreditGrantingStatus("0"); // 数据库没有这个字段
        responseVO.setAuditRecordId(""); // 数据库没有这个字段
        responseVO.setFromType("3");
        responseVO.setEmail(""); //邮箱
        responseVO.setDesc(""); //描述
        responseVO.setRealName(""); //实名
        responseVO.setIsTuandaiBao("");
        responseVO.setBirthday("");
        responseVO.setIntegral(0); //用户积分
        responseVO.setIsValidateEmail(false);
        responseVO.setIsValidateMobile(false);
        responseVO.setIsSafeQuestion(false); // 数据库没有这个字段
        responseVO.setIsPayPwd(false);
        responseVO.setIsBank(false);
        responseVO.setGuaranteeStatus("-1");
        responseVO.setBorrowerStatus("-1");
        responseVO.setSex("0");
        responseVO.setStatus("00");
        responseVO.setDesc("成功");
        data.put("user",responseVO);
        String newToken = SecurityUtils.getSubject().getSession().getId().toString();
        postLoginHandleIfLoginSuccess(request, newToken, String.valueOf(PrincipalContext.getUserId()));

        return Result.with(data);
    }

    @PostMapping("/getUserInfo")
    @ApiOperation(value = "获取用户基础信息(杨玉威)", notes = "USR19056-您的手机号输入错误 USR19007-缺少登录名 USR19009-为保障信息安全，登录密码错误超过5次，账户自动锁定24小时。 可以通过忘记密码进行解锁。 如需帮助请联系客服：400-0683-666 USR19010-缺少短信验证码 USR19011-验证码错误或过期，请重新输入 USR19006-用户不存在 USR19054-登录失败，用户名或密码错误 USR19057-密码错误，请重输！您还有1次机会，为保障信息安全，错误5次系统将锁码24小时。 USR19012-登录失败，用户名或密码错误 USR19013-登录失败，用户名或密码错误")
    @AuthIgnore
    public Result<List<Map<String,Object>>> getUserInfo(@RequestBody @Valid UserBasicInfoRequestVO requestVO) throws Throwable {

        String paramStr = requestVO.getStr();
        String[] keys = paramStr.replaceAll("，", ",").split(",");
        List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
        if(keys != null && keys.length > 0){

            for(String key : keys){
                Map<String,Object> element = new HashMap<String, Object>();
                UserBasicInfoResponseDTO userBasicInfoResponseDTO = userBasicInfoDubboService.getUserBasicInfo(key);

                if(userBasicInfoResponseDTO != null) {
                    element.put("businessId",userBasicInfoResponseDTO.getUserId());
                    element.put("nickName",userBasicInfoResponseDTO.getNickName());
                    element.put("gender",userBasicInfoResponseDTO.getGender());
                    element.put("avatar",userBasicInfoResponseDTO.getHeadImage());
                    element.put("introduction","");
                    element.put("identity",1);
                    element.put("mobile","0");
                    element.put("guarantee",0);
                    element.put("borrower",0);
                    element.put("isInvestor",1);
                    element.put("isInvestigator",0);
                    element.put("modifyTime",userBasicInfoResponseDTO.getModifyTime());
                    element.put("company","");
                    element.put("occupation","");
                    element.put("industry","");
                    element.put("area","");
                }
                if (element != null){
                    list.add(element);
                }
            }
        }


        return Result.with(list);
    }

    /**
     * 密码错误处理
     */
    private void postLoginHandleIfPasswordError(LoginRequestVO request) {
        PostLoginRequestDTO postLoginRequestDTO = new PostLoginRequestDTO();
        postLoginRequestDTO.setIsPasswordError(true);
        postLoginHandle(postLoginRequestDTO, request);
    }

    /**
     * 登录成功处理
     */
    private void postLoginHandleIfLoginSuccess(LoginRequestVO request, String token, String userId) {
        PostLoginRequestDTO postLoginRequestDTO = new PostLoginRequestDTO();
        postLoginRequestDTO.setIsPasswordError(false);
        postLoginRequestDTO.setToken(token);
        postLoginRequestDTO.setUserId(userId);
        postLoginHandle(postLoginRequestDTO, request);
    }

    /**
     * 登录后处理
     */
    private void postLoginHandle(PostLoginRequestDTO postLoginRequestDTO, LoginRequestVO request) {
        postLoginRequestDTO.setLoginMobileNo(request.getLoginMobileNo());
        if (!postLoginRequestDTO.getIsPasswordError()) {
            postLoginRequestDTO.setProvinceName(request.getProvinceName());
            postLoginRequestDTO.setCityName(request.getCityName());
            postLoginRequestDTO.setAreaName(request.getAreaName());
            postLoginRequestDTO.setAddress(request.getAddress());
            postLoginRequestDTO.setLongitude(request.getLongitude());
            postLoginRequestDTO.setLatitude(request.getLatitude());
            postLoginRequestDTO.setClientAccessIP(request.getClientAccessIP());

            postLoginRequestDTO.setMapType(request.getMapType());
            postLoginRequestDTO.setMacAddress(request.getMacAddress());
            if (!"unknown".equals(request.getWifiSSID())) {
                postLoginRequestDTO.setWifiSSID(request.getWifiSSID());
            }
            postLoginRequestDTO.setDownChannel(request.getDownChannel());
            postLoginRequestDTO.setAppVersion(request.getAppVersion());
            if (!"000".equals(request.getDeviceId())) {
                postLoginRequestDTO.setDeviceId(request.getDeviceId());
            }
            postLoginRequestDTO.setSimMobilePhone(request.getSimMobilePhone());
            postLoginRequestDTO.setOs(request.getOs());
            postLoginRequestDTO.setOsVersion(request.getOsVersion());
            postLoginRequestDTO.setResolution(request.getResolution());
            postLoginRequestDTO.setPhoneModel(request.getPhoneModel());
            postLoginRequestDTO.setBrand(request.getBrand());
            postLoginRequestDTO.setEquipmentStatus(request.getEquipmentStatus());
            postLoginRequestDTO.setDualSim(request.getDualSim());
            postLoginRequestDTO.setJiGuangPushId(request.getJiGuangPushId());
            postLoginRequestDTO.setBlackBox(request.getBlackBox());
            switch (request.getDeviceType()) {
                case "Android/mobile" : postLoginRequestDTO.setDeviceType(UserEnum.RegisterDeviceType.ANDROID); break;
                case "IOS/mobile" : postLoginRequestDTO.setDeviceType(UserEnum.RegisterDeviceType.IOS); break;
                case "H5" : postLoginRequestDTO.setDeviceType(UserEnum.RegisterDeviceType.WEB); break;
            }
        }
        userLoginAccountService.postLoginHandle(postLoginRequestDTO);
    }

    @PostMapping("/logout")
    @ApiOperation("登出")
    public Empty login(@RequestHeader(value = "token") String token) {
        redisTemplate.delete(token);
        return Empty.getInstance();
    }

	@PostMapping("/getInviteCode")
	@ApiOperation("获取邀请码")
	public Result<GetInviteCodeResponseVO> getInviteCode() {
		GetInviteCodeResponseVO responseVO = new GetInviteCodeResponseVO();
		GetInviteCodeResponseDTO responseDTO = userBasicInfoDubboService.getInviteCode(PrincipalContext.getUserId());
		responseVO.setCode(responseDTO.getCode());
		return Result.with(responseVO);
	}
}
